﻿using System;
using System.IO;

namespace MediaController.Client.Common
{
    /// <summary>
    /// 
    /// </summary>
    public sealed class ReceivedFileInfo
    {
        #region Data members

        /// <summary>
        /// 
        /// </summary>
        private readonly FileInfo _receivedFile;

        /// <summary>
        /// flag to indicate if the handler for received file event will handle the file on file system.
        /// <div>Default - false</div>
        /// <div>If false the file will be deleted as soon as the event is returned</div>
        /// </summary>
        private bool _handleFileOnFileSystem;

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="receivedFile"></param>
        /// <exception cref="ArgumentNullException">Received file is null</exception>
        public ReceivedFileInfo(FileInfo receivedFile)
        {
            if (receivedFile == null)
                throw new ArgumentNullException("receivedFile");

            _receivedFile = receivedFile;
        }

        /// <summary>
        /// flag to indicate if the handler for received file event will handle the file on file system.
        /// <div>Default - false</div>
        /// <div>If false the file will be deleted as soon as the event is returned</div>
        /// </summary>
        public bool HandleFileOnFileSystem
        {
            get { return _handleFileOnFileSystem; }
            set { _handleFileOnFileSystem = value; }
        }

        /// <summary>
        /// Gets the name of the file.
        /// </summary>
        /// <returns>
        /// The name of the file.
        /// </returns>
        /// <filterpriority>1</filterpriority>
        public string Name
        {
            get { return _receivedFile.Name; }
        }

        /// <summary>
        /// Gets the full path of the directory or file.
        /// </summary>
        /// <returns>
        /// A string containing the full path.
        /// </returns>
        /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception><filterpriority>1</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /></PermissionSet>
        public string FullName
        {
            get { return _receivedFile.FullName; }
        }

        /// <summary>
        /// Gets the size, in bytes, of the current file.
        /// </summary>
        /// <returns>
        /// The size of the current file in bytes.
        /// </returns>
        /// <exception cref="T:System.IO.IOException"><see cref="M:System.IO.FileSystemInfo.Refresh" /> cannot update the state of the file or directory. </exception>
        /// <exception cref="T:System.IO.FileNotFoundException">The file does not exist.-or- The Length property is called for a directory. </exception><filterpriority>1</filterpriority>
        public long Length
        {
            get { return _receivedFile.Length; }
        }

        /// <summary>
        /// Gets a value indicating whether a file exists.
        /// </summary>
        /// <returns>
        /// true if the file exists; false if the file does not exist or if the file is a directory.
        /// </returns>
        /// <filterpriority>1</filterpriority>
        public bool Exists
        {
            get { return _receivedFile.Exists; }
        }

        /// <summary>
        /// Gets or sets the time when the current file or directory was last written to.
        /// </summary>
        /// <returns>
        /// The time the current file was last written.
        /// </returns>
        /// <exception cref="T:System.IO.IOException"><see cref="M:System.IO.FileSystemInfo.Refresh" /> cannot initialize the data. </exception>
        /// <exception cref="T:System.PlatformNotSupportedException">The current operating system is not Microsoft Windows NT or later.</exception><filterpriority>1</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /></PermissionSet>
        public DateTime LastWriteTime
        {
            get { return _receivedFile.LastWriteTime; }
            set { _receivedFile.LastWriteTime = value; }
        }

        /// <summary>
        /// Gets or sets the creation time of the current <see cref="T:System.IO.FileSystemInfo" /> object.
        /// </summary>
        /// <returns>
        /// The creation date and time of the current <see cref="T:System.IO.FileSystemInfo" /> object.
        /// </returns>
        /// <exception cref="T:System.IO.IOException"><see cref="M:System.IO.FileSystemInfo.Refresh" /> cannot initialize the data. </exception>
        /// <exception cref="T:System.IO.DirectoryNotFoundException">The specified path is invalid, such as being on an unmapped drive. </exception>
        /// <exception cref="T:System.PlatformNotSupportedException">The current operating system is not Microsoft Windows NT or later.</exception><filterpriority>1</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /></PermissionSet>
        public DateTime CreationTime
        {
            get { return _receivedFile.CreationTime; }
            set { _receivedFile.CreationTime = value; }
        }

        /// <summary>
        /// Creates a read-only <see cref="T:System.IO.FileStream" />.
        /// </summary>
        /// <returns>
        /// A new read-only <see cref="T:System.IO.FileStream" /> object.
        /// </returns>
        /// <exception cref="T:System.UnauthorizedAccessException">path is read-only or is a directory. </exception>
        /// <exception cref="T:System.IO.DirectoryNotFoundException">The specified path is invalid, such as being on an unmapped drive. </exception>
        /// <exception cref="T:System.IO.IOException">The file is already open. </exception><filterpriority>2</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /></PermissionSet>
        public Stream OpenRead()
        {
            return _receivedFile.OpenRead();
        }

        /// <summary>
        /// Read all the file as text.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception">failed reading file</exception>
        public string ReadAllText()
        {
            return File.ReadAllText(_receivedFile.FullName);
        }

        /// <summary>
        /// Read all the file as text.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception">failed reading file</exception>
        public byte[] ReadAllBytes()
        {
            return File.ReadAllBytes(_receivedFile.FullName);
        }

        /// <summary>
        /// Permanently deletes a file.
        /// </summary>
        public void Remove()
        {
            try
            {
                _receivedFile.Delete();
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// Moves a specified file to a new location.
        /// </summary>
        /// <param name="destPath">the path to move the file to</param>
        public void MoveTo(string destPath)
        {
            string destFileName = Path.Combine(destPath, _receivedFile.Name);
            _receivedFile.MoveTo(destFileName);
        }

        /// <summary>
        /// Moves a specified file to a new location.
        /// </summary>
        /// <param name="destPath">the path to move the file to</param>
        /// <param name="newFileName">the new file name</param>
        public void MoveTo(string destPath, string newFileName)
        {
            string destFileName = Path.Combine(destPath, newFileName);
            _receivedFile.MoveTo(destFileName);
        }

        /// <summary>
        /// Copies an existing file to a new file.
        /// </summary>
        /// <param name="destPath">the path to move the file to</param>
        public void CopyTo(string destPath)
        {
            string destFileName = Path.Combine(destPath, _receivedFile.Name);
            _receivedFile.CopyTo(destFileName);
        }

        /// <summary>
        /// Copies an existing file to a new file.
        /// </summary>
        /// <param name="destPath">the path to move the file to</param>
        /// <param name="newFileName">the new file name</param>
        public void CopyTo(string destPath, string newFileName)
        {
            string destFileName = Path.Combine(destPath, newFileName);
            _receivedFile.CopyTo(destFileName);
        }

        /// <summary>
        /// Delete the file
        /// </summary>
        public void Delete()
        {
            _receivedFile.Attributes = FileAttributes.Normal;
            _receivedFile.Delete();
        }
    }
}